package org.donald.annotations;

import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;

import org.donald.service.InterfaceDemo;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.lang.annotation.Repeatable;

/**
 * 自从Java 5支持注释以来，注释变得特别受欢迎因而被广泛使用。但是有一个限制，
 * 同一个地方的不能使用同一个注释超过一次。 Java
 * 8打破了这个规则，引入了重复注释，允许相同注释在声明使用的时候重复使用超过一次。
 * 重复注释本身需要被@Repeatable注释。实际上，他不是一个语言上的改变， 只是编译器层面的改动，技术层面仍然是一样的。
 * 
 * 注释Filter被@Repeatable( Filters.class )注释。Filters 只是一个容器，它持有Filter,
 * 编译器尽力向程序员隐藏它的存在。 通过这样的方式，Filterable接口可以被Filter注释两次。
 * 
 * 另外，反射的API提供一个新方法getAnnotationsByType() 来返回重复注释的类型（
 * 请注意Filterable.class.getAnnotation( Filters.class )将会返回编译器注入的Filters实例）。
 * 
 * @author donald 2018年3月14日 下午9:42:46
 */
public class RepeatingAnnotations {
	private static final Logger log = LoggerFactory.getLogger(RepeatingAnnotations.class);

	@Target(ElementType.TYPE)
	@Retention(RetentionPolicy.RUNTIME)
	public @interface Filters {
		Filter[] value();
	}

	@Target(ElementType.TYPE)
	@Retention(RetentionPolicy.RUNTIME)
	@Repeatable(Filters.class)
	public @interface Filter {
		String value();
	};

	@Filter("filter1")
	@Filter("filter2")
	public interface Filterable {
	}

	public static void main(String[] args) {
		for (Filter filter : Filterable.class.getAnnotationsByType(Filter.class)) {
			log.info(filter.value());
		}
	}
}
